package com.walala.logic.client;

import com.walala.logic.common.Constant;
import com.walala.logic.protocol.ProtocolPackage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class ClientDecoder extends ByteToMessageDecoder {

	private Logger logger = LoggerFactory.getLogger(ClientDecoder.class);

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {

		try {
			ProtocolPackage pack = new ProtocolPackage();

			//标记当前readindex位置
			buf.markReaderIndex();
			//判断包头长度
			int readableBytes = buf.readableBytes();
			if(readableBytes < (Constant.PACK_HEAD_LENGTH + 1)){
				buf.resetReaderIndex();
				return;
			}
			byte startTag = buf.readByte();
			if (startTag != Constant.pack_start_tag) {
				logger.error("数据包解码异常，数据包非法");
				ctx.close();
				return;
			}
			ByteBuf head = buf.readBytes(Constant.PACK_HEAD_LENGTH );
			short totalLength = head.readShort();
			short cmd = head.readShort();
			long senderId = head.readLong();
			byte clientId = head.readByte();
			byte version = head.readByte();
			byte result = head.readByte();
			long time = head.readLong();
			long receiverId = head.readLong();
			int traceId=head.readInt();
			byte ack=head.readByte();
			// 计算有效数据长度
			int leftLength = totalLength - Constant.PACK_HEAD_LENGTH  - 2;
			if (buf.readableBytes() < leftLength) {// 长度不够
				buf.resetReaderIndex();
				logger.info("[decoder]报文长度不够.uid is {}",senderId);
				return;
			}

			ByteBuf protoBody = buf.readBytes(leftLength);
			byte endTag = buf.readByte();
			// 封装协议对象
			byte[] headArr = new byte[Constant.PACK_HEAD_LENGTH ];
			head.readerIndex(0);
			head.readBytes(headArr);
			pack.setHead(headArr);
			pack.setStartTag(startTag);
			pack.setLength(totalLength);
			pack.setCommand(cmd);
			pack.setSenderId(senderId);
			pack.setClientType(clientId);
			pack.setVersion(version);
			pack.setClientType(clientId);
			pack.setResult(result);
			pack.setStime(System.currentTimeMillis());
			pack.setReceiverId(receiverId);
			pack.setTraceId(traceId);
			byte[] bodyArr = new byte[leftLength];
			protoBody.readBytes(bodyArr);
			pack.setProtoBody(bodyArr);
			pack.setEndTag(endTag);
			pack.setAck(ack);
			out.add(pack);
			logger.info("解码完成,cmd:[{}],senderId:[{}],time:[{}],traceId:[{}]",cmd,senderId,time,traceId);
		} catch (Exception e) {
			logger.error("解码异常，error：",e);
		}

	}

}
